package com.demo.wordex.utils;

import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

/**
 * Word 工具类
 *
 * @author 秋牧
 * 2024/7/25 11:48
 */
@Slf4j
@Component
public class WordUtil {

    /**
     * 基于模板生成 Word 文档
     *
     * @param response         response
     * @param basePackagePath  resources 目录下模板所在包路径
     * @param templateFileName 模板文件名
     * @param templateParam    模板参数
     * @param fileName         文件名
     */
    public void generate(HttpServletResponse response, String basePackagePath, String templateFileName, Object templateParam, String fileName) {
        try {
            // 设置 HTTP 响应的内容类型为 Microsoft Word 文档
            response.setContentType("application/msword");
            // 设置响应字符编码为 UTF-8
            response.setCharacterEncoding("utf-8");
            // 使用 URLEncoder 对文件名进行编码，以防止中文文件名在不同浏览器和操作系统下出现乱码问题
            String filename = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8");
            // 设置响应头，指定文档将以附件的形式下载，并定义文件名
            response.setHeader("Content-disposition", "attachment;filename=" + filename + ".doc");
            // 创建 Freemarker 的 Configuration 对象，设置默认的不兼容改进选项
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setDefaultEncoding("utf-8");
            // 设置模板加载器，加载模板文件
            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
            Template t = configuration.getTemplate(templateFileName, "utf-8");
            // 创建 Writer 对象，用于将生成的文档写到输出流中，缓存区大小设为 10KB
            Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8), 10240);
            // 将模型数据与模板结合生成 Word 文档，写入到 Writer 对象中
            t.process(templateParam, out);
            out.close();
        } catch (Exception e) {
            log.info("基于模板{}生成Word文档异常，异常原因：{}", templateFileName, e.getMessage(), e);
            throw new RuntimeException("生成Word文档异常，异常原因：" + e.getMessage());
        }
    }

    /**
     * 基于模板生成 Word 文档到指定文件夹
     *
     * @param outputDir        输出文件夹
     * @param basePackagePath  resources 目录下模板所在包路径
     * @param templateFileName 模板文件名
     * @param templateParam    模板参数
     * @param fileName         文件名
     */
    public void generate(String outputDir, String basePackagePath, String templateFileName, Object templateParam, String fileName) {
        try {
            // 创建 Freemarker 的 Configuration 对象，设置默认的不兼容改进选项
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setDefaultEncoding("utf-8");
            // 设置模板加载器，加载模板文件
            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
            Template t = configuration.getTemplate(templateFileName, "utf-8");
            // 构建输出文件的完整路径
            File outputFile = new File(outputDir, fileName + "_" + System.currentTimeMillis() + ".doc");
            // 创建 Writer 对象，用于将生成的文档写到输出流中，缓存区大小设为 10KB
            Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outputFile.toPath()), StandardCharsets.UTF_8), 10240);
            // 将模型数据与模板结合生成 Word 文档，写入到 Writer 对象中
            t.process(templateParam, out);
            out.close();
        } catch (Exception e) {
            log.info("基于模板{}生成Word文档异常，异常原因：{}", templateFileName, e.getMessage(), e);
            throw new RuntimeException("生成Word文档异常，异常原因：" + e.getMessage());
        }
    }

}
